import numpy as np
#GDA is a genarative learning algo

#
X_train = np.loadtxt('X_train.txt', delimiter=',')
y_train = np.loadtxt('y_train.txt', delimiter=',')
X_test = np.loadtxt('X_test.txt', delimiter=',')
y_test = np.loadtxt('y_test.txt', delimiter=',')
m = y_train.shape[0]
n = X_train.shape[1]
phi = 0
mu0 = np.zeros((n,1))
mu1 = 0
sigma = 0

#solve
for i in range(m):
    phi = phi + y_train[i]
    mu0 = mu0 + (1 - y_train[i]) * X_train[i].T
    mu1 = mu1 + y_train[i] * X_train[i].T
mu0 = mu0 / (m - phi)
mu1 = mu1 / phi
phi = phi / m
for i in range(m):
    if y_train[i] == 0:
        sigma = sigma + np.dot(X_train[i].T - mu0, X_train[i] - mu0.T)
    else:
        sigma = sigma + np.dot(X_train[i].T - mu1, X_train[i] - mu1.T)
sigma = sigma / m

#predict
y_equal_0 = 1 - phi
y_equal_1 = phi
y_equal_0_x = np.exp((-1/2) * np.dot(np.dot((X_test - mu0).T, np.linalg.inv(sigma)), X_test - mu0)) / ((((2 * np.pi)**n)*np.linalg.det(sigma))**(1/2))
y_equal_1_x = np.exp((-1/2) * np.dot(np.dot((X_test - mu1).T, np.linalg.inv(sigma)), X_test - mu1)) / ((((2 * np.pi)**n)*np.linalg.det(sigma))**(1/2))
prediction = (y_equal_1_x * y_equal_1) / (y_equal_0_x * y_equal_0 + y_equal_1_x * y_equal_1)

